/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package session.stateless;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import entity.Employee;
import java.util.Date;
import java.util.Calendar;
import java.util.ArrayList;
import entity.AccessRole;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import javax.ejb.EJB;

@Stateless
public class EmployeeSessionBean implements EmployeeSessionBeanLocal, EmployeeSessionBeanRemote {

    @PersistenceContext
    private EntityManager entityManager;
    @EJB
    PasswordSecurityLocal passwordSecurityLocal;
    @EJB
    CustomerSessionBeanLocal customerSessionBeanLocal;

    @Override
    public Employee getEmployee(String userId) {
        Employee employee = entityManager.find(Employee.class, userId);
        return employee;
    }

    @Override
    public ArrayList<Employee> getEmployees() {
        Query query = entityManager.createQuery("SELECT u FROM Employee u");
        ArrayList<Employee> employees = new ArrayList<Employee>();
        for (Object o : query.getResultList()) {
            Employee e = (Employee) o;
            if (e.getAccountStatus().compareTo("EXPIRE") == 0) {
            } else {
                employees.add(e);
            }
        }
        return employees;
    }

    @Override
    public ArrayList<Employee> getEmployees(ArrayList<AccessRole> rlist) {
        Query query = entityManager.createQuery("SELECT u FROM Employee u");
        ArrayList<Employee> employees = new ArrayList<Employee>();
        for (Object o : query.getResultList()) {
            Employee e = (Employee) o;
            
            if (e.getAccountStatus().compareTo("EXPIRE") == 0) {
            } else {
                for (AccessRole ar : e.getAccessRoles()) {
                    Boolean found = false;
                    for (AccessRole role : rlist) {
                        if (ar.getRoleType().compareTo(role.getRoleType()) == 0) {
                            found = true;
                        }
                    }
                    if (found) {
                        employees.add(e);
                    }
                }
            }
        }

        HashSet set = new HashSet(employees);
        
        employees.clear();
        employees.addAll(set);
        
        return employees;
    }

    @Override
    public ArrayList<Employee> getEmployees(String department) {
        Query query = entityManager.createQuery("SELECT u FROM Employee u WHERE u.department = :indepartment");
        query.setParameter("indepartment", department);
        
        ArrayList<Employee> employees = new ArrayList<Employee>();
        
        for (Object o : query.getResultList()) {
            Employee e = (Employee) o;
            
            if (e.getAccountStatus().compareTo("EXPIRE") == 0) {
            } else {
                if (e.getDesignation().compareTo("Executive") == 0 || e.getDesignation().compareTo("Manager") == 0) {
                    employees.add(e);
                }
            }
        }
        
        return employees;
    }

    @Override
    public void addEmployee(String userId, String userPassword, String name, Integer contactOffice, Integer contactMobile, String emailAddress, String department, String accountStatus, Date passwordExpiry, Integer invalidCounter, String designation, Date dob) {
        System.out.println(userId);
        String temp = passwordSecurityLocal.encrypt(userPassword);
        Employee employee = new Employee(userId, temp, name, contactOffice, contactMobile, emailAddress, department, accountStatus, passwordExpiry, invalidCounter, designation, dob);

        entityManager.persist(employee);
        entityManager.flush();
    }

    @Override
    public String getPassword(String userId) {
        Employee employee = getEmployee(userId);
        
        String pwd = employee.getUserPassword();
        String temp = passwordSecurityLocal.decrypt(pwd);
        
        return temp;
    }

    @Override
    public Integer loginEmployee(String userId, String userPassword) {
         Employee employee = getEmployee(userId);
        if (employee != null) {
            String pwd = employee.getUserPassword();
            String temp = passwordSecurityLocal.decrypt(pwd);

            if (temp.compareTo(userPassword) == 0) {
                if (employee.getAccountStatus().compareTo("ACTIVE") == 0) {
                    System.out.println("Login as " + userId);
                    Date d = new Date();
                    if (employee.getPasswordExpiry().before(d)) {
                        return 2; //password expire
                    }
                    return 1; //login OK
                } else {
                    return 0; //account lock or expire
                }
            } else {
                return -1; //password mismatch
            }
        }
        
        return -1;
    }

    @Override
    public void updateLogin(String userId, Integer counter) {
        Query query = entityManager.createQuery("SELECT u FROM Employee u WHERE u.userId = :inuserId");
        query.setParameter("inuserId", userId);
        Employee employee = null;

        try {
            employee = (Employee) query.getSingleResult();
        } catch (Exception ex) {
        }

      /*  if (employee != null) {
            if (counter == 0) {
                counter = employee.getInvalidCounter() + 1;
                employee.setInvalidCounter(counter);

                if (counter > 4) {
                    employee.setAccountStatus("LOCK");
                      employee.setInvalidCounter(counter);
                }
            } else {
                employee.setInvalidCounter(counter);
            }

            entityManager.persist(employee);
            entityManager.flush();

        }*/
        
         if (employee != null) 
         {
            if (counter >= 1) 
            {
                System.out.println("Login" + counter);
                counter = employee.getInvalidCounter() + 1;
                System.out.println("Login 1" + counter);
                employee.setInvalidCounter(counter);

                if (counter > 4) 
                {
                    employee.setAccountStatus("LOCK");
                    System.out.println("Login 2" + counter);
                }
            } 
            else 
            {
                employee.setInvalidCounter(counter);
            }

            entityManager.persist(employee);
            entityManager.flush();
          
         }
        }
    

    @Override
    public Date updatePassword(String userId, String userPassword) {
        Employee employee = getEmployee(userId);

        String temp = passwordSecurityLocal.encrypt(userPassword);
        employee.setUserPassword(temp);
        Date d = new Date();
        Calendar cal = Calendar.getInstance();
        cal.add(cal.MONTH, 3);
        d = cal.getTime();
        employee.setPasswordExpiry(d);
        employee.setInvalidCounter(0);
        
        entityManager.persist(employee);
        entityManager.flush();
        
        return d;
    }

    @Override
    public void updatePassword(String userId, String userPassword, Date passwordExpiry) {
        Employee employee = getEmployee(userId);
        String temp = passwordSecurityLocal.encrypt(userPassword);
        employee.setUserPassword(temp);
        employee.setPasswordExpiry(passwordExpiry);
        employee.setInvalidCounter(0);
        entityManager.persist(employee);
        entityManager.flush();
    }

    @Override
    public void updateEmployee(String userId, String name, Integer contactOffice, Integer contactMobile, String emailAddress, String department, String accountStatus, Date passwordExpiry, Integer invalidCounter, String designation, Date dob) {
        try {
            Employee employee = entityManager.find(Employee.class, userId);
            
            employee.setName(name);
            employee.setContactOffice(contactOffice);
            employee.setContactMobile(contactMobile);
            employee.setDepartment(department);
            employee.setEmailAddress(emailAddress);
            employee.setAccountStatus(accountStatus);
            employee.setPasswordExpiry(passwordExpiry);
            employee.setInvalidCounter(invalidCounter);
            employee.setDesignation(designation);
            employee.setDob(dob);
            
            entityManager.persist(employee);
            entityManager.flush();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void deleteEmployee(String userId) {
        Employee employee = entityManager.find(Employee.class, userId);
        
        if (employee != null) {
            customerSessionBeanLocal.unassignCustomers(employee.getUserId());
            
            employee.setAccountStatus("EXPIRE");
        }
    }
    
    @Override
    public void tempDeleteEmployee(String userId) {
        Employee employee = entityManager.find(Employee.class, userId);
        if (employee != null) {
           entityManager.remove(employee);
        }

    }


    @Override
    public ArrayList<String> getRoles(String userId) {
        Employee employee = entityManager.find(Employee.class, userId);
        
        ArrayList<String> a = new ArrayList<String>();
        
        for (AccessRole o : employee.getAccessRoles()) {
            a.add(o.getRoleType());
        }
        
        return a;
    }

    @Override
    public void updateAccessRole(String userId, String role, Boolean addRole) {
        Employee employee = entityManager.find(Employee.class, userId);
        Collection<AccessRole> roles = employee.getAccessRoles();

        AccessRole a = entityManager.find(AccessRole.class, role);
        if (addRole) {
            roles.add(a);
        } else {
            roles.remove(a);
        }

        entityManager.persist(employee);
        entityManager.flush();
    }

    @Override
    public List<String> getDesignations() {
        ArrayList al = new ArrayList();

        Query query = entityManager.createQuery("SELECT DISTINCT e.designation FROM Employee e ORDER BY e.designation ASC");

        for (Object o : query.getResultList()) {
            String s = (String) o;
            
            al.add(s);
        }

        return al;
    }
    
    
}
